/*
 * :Author: 沈玲玲
 * :Company: 蓝萌电子
 * :Date: 2023-06-01 02:48:27
 * :LastEditTime: 2023-06-01 04:01:40
 * :LastEditors: 沈玲玲
 * :FilePath: \TiantuBUSDemo\lib\TiantuBus.h
 * :Version: 1.0.0
 * :Language: C/C++
 * :Coding: UTF-8
 * :Copyright: 2023 蓝萌电子.
 * :All Rights Reserved.
 * :This software component is licensed under GPL-3.0.
 * :You may not use this file except in compliance with the License.
 * :Description: 蓝萌电子专属数据协议：TiantuBus。
 * 可以适用于单片机与上位机，单片机与单片机之间的通信，支持IIC,SPI,UART等
 * 通信协议，支持STM32,51,AVR,STM8等多种类型的单片机，只要是蓝萌电子开发
 * 的设备，在知道机器编号的情况下，便可以直接使用通信协议，并拥有专属调试的
 * 串口助手。
 * 
 * 格式：
 * 1.发送命令（控制寄存器）
 * 前导码（2字节） +  目标设备编号（2字节） + 操作类型（1字节）
 * + 命令（1字节）+ 寄存器地址（1字节）+ 校验（1字节）+ 包尾（2字节）
 * 总长度：10个字节
 * 返回：应答拓展指令
 * 
 * 2.发送数据（设置储存变量的值）
 * 前导码（2字节） +  目标设备编号（2字节） + 操作类型（1字节）
 * + 数据长度（2字节）+ 数据包内容（N字节）+ 存储器地址（2字节）
 * + 校验（1字节）+ 包尾（2字节）
 * 总长度：12 + N个字节
 * 返回：应答拓展指令
 * 
 * 3.访问寄存器（读取寄存器）
 * 前导码（2字节） +  目标设备编号（2字节） + 操作类型（1字节）
 * + 寄存器地址（1字节） + 校验（1字节）+ 包尾（2字节）
 * 总长度：9字节
 * 返回：前导码（2字节）+ 目标设备编号（2字节）+ 操作类型（1字节）
 * + 寄存器内容（1字节）+ 寄存器地址（1字节）+ 校验（1字节）
 * + 包尾（2字节）
 * 总长度：10字节
 * 
 * 4.读取数据（读取数据的值）
 * 前导码（2字节） +  目标设备编号（2字节） + 操作类型（1字节）
 * + 数据长度（2字节）+ 储存器地址（2字节） + 校验（1字节）
 * + 包尾（2字节）
 * 总长度：12字节
 * 返回：前导码（2字节）+ 目标设备编号（2字节）+ 操作类型（1字节）
 * + 储存器内容（N字节）+ 储存器地址（2字节）+ 校验（1字节）
 * + 包尾（2字节）
 * 总长度：10 + N字节
 * 
 * 5.拓展指令（设置单片机属性专用）
 * 前导码（2字节）+ 目标设备编号（2字节）+ 命令（1字节）
 * + 校验（1字节）+ 包尾（2字节）
 * 总长度：8字节
 */

#ifndef  __TIANTUBUS_H__
#define  __TIANTUBUS_H__

#include "main.h"
/**
 * 可以自己修改的代码部分
 */
//本机编号  自己定义，但不同的设备编号必须不同
#define Unit_Number 0xabcd
//本机生产时间
#define Unit_Time_Year 2023
#define Unit_Time_Month 6
#define Unit_Time_Day 1

//发送，接收缓存大小
//#define __TINY_MEMORY__ 1
#define __MEDIUM_MEMORY__ 1
//#define __HUGE_MEMORY__ 1

//小容量单片机，如51，Arduino等
#ifdef __TINY_MEMORY__   
#define BUFFER_SIZE 16
#endif

//标准容量单片机，如STM32等（推荐使用）
#ifdef __MEDIUM_MEMORY__
#define BUFFER_SIZE 256  
#endif

//超大容量单片机
#ifdef __HUGE_MEMORY__
#define BUFFER_SIZE 2048  
#endif

/**
 * 固定部分,建议不要修改
 */
//前导码2个字节 "Y" + "m" 0x59 0x6D
#define Head_Code_1 0x59
#define Head_Code_2 0x6D

//包尾2个字节 "Q" + "e" 0x51 0x65
#define Tail_Code_1 0x51
#define Tail_Code_2 0x65

//当前状态
#define STATE_IDLE 0x00                    //空闲：未连接
#define STATE_WAITING_CONNECTING 0x10      //等待连接
#define STATE_CONNECTED 0x20               //已连接
#define STATE_WAITING_DATA 0x30            //等待数据回应

//操作类型
#define CTRL_NONE 0X00
#define CTRL_WRITE_DATA 0x81    //写数据
#define CTRL_WRITE_CMD 0x82     //写命令
#define CTRL_READ_DATA 0x83     //读数据
#define CTRL_READ_CMD 0x84      //读命令
#define CTRL_EXPAND 0x85        //拓展指令

#define RESEND_CMD 0x74         //回发寄存器的命令
#define RESEND_DATA 0x73        //回发数据的值

//拓展指令
#define HAND_SHAKE 0x39         //尝试握手指令
#define ACK_CMD    0xc0         //回复应答指令

//
#define ALL_ADDR 0xffff         //广播模式，无视地址，对线上所有设备同时发送信息
/**
 * 以下为TiantuBus的执行函数
 */
//初始化
void TiantuBus_Init(void);
//TiantuBus发送函数
void TiantuBus_Transmit_Cmd(uint16_t target_unit,uint8_t cmd,uint8_t reg_addr);						   //发送命令
void TiantuBus_Transmit_Data(uint16_t target_unit,uint16_t data_length,uint8_t *dat,uint16_t dat_addr);//发送数据
void TiantuBus_Transmit_Expand(uint16_t target_unit,uint8_t expand_cmd);

uint8_t buffer_handle(void);
void add_to_recv_buf(uint8_t dat);
uint8_t TiantuBus_1ms_task(void);
//和校验
uint8_t check_sum(uint8_t *buf,uint8_t len);
#endif
